//
//  PlayingScreen.m
//  cocos2dFirstTest
//
//  Created by Daniel Alexander on 6/17/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "PlayingScreen.h"
#import <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if TARGET_OS_IPHONE
#import <CFNetwork/CFNetwork.h>
#endif
#import "Classes/SBJson.h"

/*We're Gonna Need to do a lot here:
    >We need to set up the socket connection to the server.
    >Handle messages from the server
    >send messages to the server
    >update game screen
    >handle the map
    >handle input
*/

@implementation PlayingScreen

+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	PlayingScreen *layer = [PlayingScreen node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
    //CCDirector *director = [CCDirector sharedDirector];
    
	// return the scene
	return scene;
}


// on "init" you need to initialize your instance
-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super" return value
	if( (self=[super init])) {
        NSLog(@"started playing game screen");
        connectionLayer = [ConnectionLayer node];
        [self addChild:connectionLayer];
        
        theMap = [MapLayer node];
        [self addChild:theMap];
        
        uiLayer = [[UILayer alloc] initWithPlayingScreen:self];
        [uiLayer setVisible: NO];
        [self addChild:uiLayer];
        
        NSLog(@"schedule update...");
        [self scheduleUpdate];
        
        // Create socket.
        NSLog(@"create socket connection...");
        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,(CFStringRef) @"192.168.42.1",7000,&myReadStream,&myWriteStream);
        NSLog(@"socket created...");
        
        //SPAWN LISTENER THREAD
        NSLog(@"create listen thread");
        [NSThread detachNewThreadSelector:@selector(ListenThread:) toTarget:self withObject:nil];
        
        // send first message
        NSLog(@"send first message");
        if (myWriteStream != NULL && CFWriteStreamOpen(myWriteStream))
        {
            // Write a byte.
            //message_id, name, class
            NSString  *msg = [[NSDictionary dictionaryWithObjectsAndKeys:
                             @"login", @"message_id",
                             @"player", @"name",
                             @"warrior", @"class", nil] JSONRepresentation];
            //msg = [msg stringByAppendingString:@"\n"];
            const UInt8 *writeBuffer =  (const UInt8 *)[msg UTF8String];
            int size = [msg length];
            
            //every once in a while, the game hangs right here. not sure why, and it
            //doesn't happen every time.
            CFWriteStreamWrite(myWriteStream, writeBuffer, size);
        }
        
        NSLog(@"init done...");
    }
	return self;
}

-(void)ListenThread:(id)param{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
        // Open read stream.
        if (myReadStream != NULL && CFReadStreamOpen(myReadStream))
        {
            NSString *wholeMSG = @"";
            UInt8 readBuffer[512];
            SBJsonParser *parser = [[SBJsonParser alloc] init];
            int tmp = 1;
            while(true)
            {
                
                while (CFReadStreamHasBytesAvailable(myReadStream))
                {
                    // Read bytes.
                    int bytesRead = CFReadStreamRead(myReadStream, readBuffer, 511);
                    readBuffer[bytesRead] = '\0';
                    NSString *msg = [NSString stringWithUTF8String:readBuffer];
                    NSRange range;
                    
                    if (bytesRead > 0)
                    {
                        wholeMSG = [wholeMSG stringByAppendingFormat:@"%@", msg];
                        //[testLabel setString:@"test"];
                        tmp += 1;
                    }
                    
                    while ((range = [wholeMSG rangeOfString:@"\n"]).location != NSNotFound)
                    {
                        //do something with the message
                        NSString *chunk = [wholeMSG substringToIndex:range.location];
                        NSLog(@"received data: %@", chunk);
                        
                        //TAKE THE CHUNK AND PROCESS IT
                        NSDictionary *message = [parser objectWithString:chunk];
                        
                        if ([[message objectForKey:@"message_id"] isEqualToString:@"dungeon_map"])
                        {
                            //message is the dungeon map
                            [theMap SetMap:[message objectForKey:@"map"]];
                        }
                        else if ([[message objectForKey:@"message_id"] isEqualToString:@"login_response"])
                        {
                            //message is the login response
                            if ([[message objectForKey:@"success"] boolValue] == true)
                            {
                                connected = YES;
                            }
                            else{
                                connected = NO;
                            }
                        }
                        else if ([[message objectForKey:@"message_id"] isEqualToString:@"party"])
                        {
                            //message is the party data
                            id players = [message objectForKey:@"players"];
                            [theMap UpdateParty:players];
                        }else if ([[message objectForKey:@"message_id"] isEqualToString:@"stats"])
                        {
                            //update player stats
                        }
                        
                        //keep using the rest of the message
                        if ([wholeMSG length] <= range.location + 1) {
                            wholeMSG = @"";
                        }
                        else {
                            wholeMSG = [wholeMSG substringFromIndex:range.location + 1];
                        }
                    }
                }
                usleep(1);
            }
        }
    [pool drain];
}

-(void)update:(ccTime)deltaTime{
    if (connected == NO || [theMap IsMapLoaded] == NO)
    {
        connectionLayer.visible = YES;
    }
    else
    {
        connectionLayer.visible = NO;
        [uiLayer setVisible: YES];
    }
}

//SEND A MOVE MESSAGE TO THE SERVER
-(void)MovePlayer:(NSInteger)xDelta y:(NSInteger)yDelta{
    NSString *dir;
    
    if (xDelta == -1 && yDelta == 0)
        dir = @"W";
    else if (xDelta == 0 && yDelta == -1)
        dir = @"N";
    else if (xDelta == 0 && yDelta == 1)
        dir = @"S";
    else if (xDelta == 1 && yDelta == 0)
        dir = @"E";
    
    //{"message_id":"move","direction":"dir"}
    // send move message
   // if (myWriteStream != NULL && CFWriteStreamOpen(myWriteStream))
    {
        // Write a byte.
        //message_id, name, class
        NSString  *msg = [[NSDictionary dictionaryWithObjectsAndKeys:
                           @"move", @"message_id",
                           dir, @"direction", nil] JSONRepresentation];
        const UInt8 *writeBuffer =  (const UInt8 *)[msg UTF8String];
        int size = [msg length];

        //every once in a while, the game hangs right here. not sure why, and it
        //doesn't happen every time.
        CFWriteStreamWrite(myWriteStream, writeBuffer, size);
        NSLog(@"sent move message with direction:%@", dir);
    }
    
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	// in case you have something to dealloc, do it in this method
	// in this particular example nothing needs to be released.
	// cocos2d will automatically release all the children (Label)
	
    // Be a good citizen.
    CFReadStreamClose(myReadStream);
    CFWriteStreamClose(myWriteStream);
    CFRelease(myReadStream);
    CFRelease(myWriteStream);
    
	// don't forget to call "super dealloc"
	[super dealloc];
}

@end
